{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ee5fef2f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "load_dotenv()\n",
    "\n",
    "# Configure an LLM\n",
    "llm = ChatOpenAI(\n",
    "    model=\"qwen3-32b\",\n",
    "    temperature=0.5,\n",
    "    base_url=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n",
    "    api_key=os.environ.get(\"AI_DASHSCOPE_API_KEY\"),\n",
    "    streaming=True,\n",
    "    extra_body={\"enable_thinking\": False}\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "656415ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from pydantic import BaseModel, Field\n",
    "\n",
    "tagging_prompt = ChatPromptTemplate.from_template(\n",
    "    \"\"\"\n",
    "    Extract the desired information from the following passage.\n",
    "    passage:\n",
    "    {input}\"\"\"\n",
    ")\n",
    "\n",
    "class Classification(BaseModel):\n",
    "    sentiment: str = Field(description=\"The sentiment of the text\")\n",
    "    aggressiveness: int = Field(\n",
    "        description=\"How aggressive the text is on a scale from 1 to 10\"\n",
    "    )\n",
    "    language: str = Field(description=\"The language the text is written in\")\n",
    "\n",
    "structured_llm = llm.with_structured_output(Classification)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "864cb181",
   "metadata": {},
   "outputs": [],
   "source": [
    "input = \"I'm incredibly glad I met you! I think we'll be great friends!\"\n",
    "prompt = tagging_prompt.invoke({\"input\": input})\n",
    "response = structured_llm.invoke(prompt)\n",
    "response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21b1cab2",
   "metadata": {},
   "outputs": [],
   "source": [
    "input = \"真高兴认识你！我想我们会成为很好的朋友！\"\n",
    "prompt = tagging_prompt.invoke({\"input\": input})\n",
    "response = structured_llm.invoke(prompt)\n",
    "response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "62d265cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "response.model_dump()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0165694",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Classification(BaseModel):\n",
    "    sentiment: str = Field(..., enum=[\"happy\", \"neutral\", \"sad\"])\n",
    "    aggressiveness: int = Field(\n",
    "        ...,\n",
    "        description=\"describes how aggressive the statement is, the higher the number the more aggressive\",\n",
    "        enum=[1, 2, 3, 4, 5],\n",
    "    )\n",
    "    language: str = Field(..., enum=[\"chinese\", \"english\", \"japanese\"])\n",
    "\n",
    "structured_llm = llm.with_structured_output(Classification)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "36d3923c",
   "metadata": {},
   "outputs": [],
   "source": [
    "input = \"真高兴认识你！我想我们会成为很好的朋友！\"\n",
    "prompt = tagging_prompt.invoke({\"input\": input})\n",
    "response = structured_llm.invoke(prompt)\n",
    "response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f57f3443",
   "metadata": {},
   "outputs": [],
   "source": [
    "input = \"你真是我遇到过的最差劲的人了！\"\n",
    "prompt = tagging_prompt.invoke({\"input\": input})\n",
    "response = structured_llm.invoke(prompt)\n",
    "response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1bae9434",
   "metadata": {},
   "outputs": [],
   "source": [
    "input = \"あなたに会えて本当に嬉しいです！きっと良い友達になれると思います！\"\n",
    "prompt = tagging_prompt.invoke({\"input\": input})\n",
    "response = structured_llm.invoke(prompt)\n",
    "response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "153b15e1",
   "metadata": {},
   "outputs": [],
   "source": [
    "input = \"Estoy increiblemente contento de haberte conocido! Creo que seremos muy buenos amigos!\"\n",
    "prompt = tagging_prompt.invoke({\"input\": input})\n",
    "response = structured_llm.invoke(prompt)\n",
    "response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "475edb6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import Optional\n",
    "\n",
    "class Person(BaseModel):\n",
    "    \"\"\"Information about a person.\"\"\"\n",
    "\n",
    "    name: Optional[str] = Field(default=None, description=\"The name of the person\")\n",
    "    hair_color: Optional[str] = Field(\n",
    "        default=None, description=\"The color of the person's hair if known\"\n",
    "    )\n",
    "    height_in_meters: Optional[str] = Field(\n",
    "        default=None, description=\"Height measured in meters\"\n",
    "    )\n",
    "\n",
    "structured_llm = llm.with_structured_output(Person)\n",
    "\n",
    "prompt_template = ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        (\n",
    "            \"system\",\n",
    "            \"You are an expert extraction algorithm. \"\n",
    "            \"Only extract relevant information from the text. \"\n",
    "            \"If you do not know the value of an attribute asked to extract, \"\n",
    "            \"return null for the attribute's value.\",\n",
    "        ),\n",
    "        (\"human\", \"{text}\"),\n",
    "    ]\n",
    ")\n",
    "\n",
    "\n",
    "text = \"Alan Smith is 6 feet tall and has blond hair.\"\n",
    "prompt = prompt_template.invoke({\"text\": text})\n",
    "structured_llm.invoke(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e4a2270",
   "metadata": {},
   "outputs": [],
   "source": [
    "class People(BaseModel):\n",
    "    \"\"\"Extracted data about people.\"\"\"\n",
    "\n",
    "    people: list[Person]\n",
    "\n",
    "structured_llm = llm.with_structured_output(People)\n",
    "\n",
    "text = \"My name is Jeff, my hair is black and i am 6 feet tall. Anna has the same color hair as me.\"\n",
    "prompt = prompt_template.invoke({\"text\": text})\n",
    "structured_llm.invoke(prompt)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
